﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;

namespace Circa.Tools {

    class TaggedString: DynamicObject {
        private readonly string source;
        private readonly Dictionary<string, IEnumerable<string>> pieces;
        private readonly MutableLookup<string, Tuple<int, int>> descriptors;

        public TaggedString( string source, params KeyValuePair<string, Tuple<int, int>> descriptors ) {
            this.source = source;
            this.descriptors = new MutableLookup<string, Tuple<int, int>>( );
            foreach ( var descriptor in descriptors )
                this.descriptors.Add( descriptor.Key, descriptor.Value );
            pieces = new Dictionary<string, IEnumerable<string>>( );
        }

        public static implicit operator string( TaggedString str ) {
            return str.source;
        }

        public void AddDescriptor( string descriptor, int start, int length ) {
            descriptors.Add( descriptor, Tuple.Create( start, length ) );
        }

        public override bool TryGetMember( GetMemberBinder binder, out object result ) {
            var name = binder.Name;
            result = this[ name ];
            return result != null;
        }

        public IEnumerable<string> this[ string descriptor ] {
            get {
                if ( pieces.ContainsKey( descriptor ) )
                    return pieces[ descriptor ];
                else {
                    if ( !descriptors[ descriptor ] )
                        return null;
                    else {
                        List<string> pieces = new List<string>( );
                        foreach ( var extent in descriptors[ descriptor ] )
                            pieces.Add( source.Substring( extent.Item1, extent.Item2 ) );
                        this.pieces[ descriptor ] = pieces;
                        return pieces;
                    }
                }
            }
        }
    }

}
